package org.orz.story.pms.biz.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import org.orz.cloud.auth.UserUtil;
import org.orz.cloud.auth.domain.UserInfo;
import org.orz.cloud.common.enums.AliveFlagEnum;
import org.orz.story.pms.biz.model.req.*;
import org.orz.story.pms.biz.model.resp.ListRoleWithGrantStatusResp;
import org.orz.story.pms.biz.persistence.entities.*;
import org.orz.story.pms.biz.persistence.mappers.*;
import org.orz.story.pms.biz.service.PmsRoleService;
import org.orz.story.pms.common.exception.PmsException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class PmsRoleServiceImpl implements PmsRoleService {
    @Autowired
    private PmsRoleMapper pmsRoleMapper;
    @Autowired
    private PmsAccountRoleMapper pmsAccountRoleMapper;
    @Autowired
    private PmsAccountMapper pmsAccountMapper;
    @Autowired
    private PmsWorkbenchMapper pmsWorkbenchMapper;
    @Autowired
    private PmsRoleApiMapper pmsRoleApiMapper;
    @Autowired
    private PmsRolePermissionMapper pmsRolePermissionMapper;


    @Override
    public List<PmsRole> listRoleInfo(ListRoleInfoReq req) {
        PageHelper.startPage(req.getPageInfo());
        return pmsRoleMapper.selectList(new LambdaQueryWrapper<PmsRole>()
                .eq(PmsRole::getAliveFlag, AliveFlagEnum.ALIVE.getKey())
                .orderByDesc(PmsRole::getId));
    }

    @Override
    public List<ListRoleWithGrantStatusResp> listRoleWithGrantStatus(ListRoleWithGrantStatusReq req) {
        PmsAccount pmsAccount = pmsAccountMapper.selectOne(new LambdaQueryWrapper<PmsAccount>()
                .eq(PmsAccount::getMemAccountId, req.getMemAccountId())
                .eq(PmsAccount::getAliveFlag, AliveFlagEnum.ALIVE.getKey()));
        if(pmsAccount == null){
            throw new PmsException(PmsException.Type.PMS_0004);
        }

        List<PmsAccountRole> accountRoles = pmsAccountRoleMapper.selectList(new LambdaQueryWrapper<PmsAccountRole>()
                .eq(PmsAccountRole::getAccountId, pmsAccount.getId())
                .eq(PmsAccountRole::getAliveFlag, AliveFlagEnum.ALIVE.getKey()));
        Set<Long> grantedRoleIds = accountRoles.stream().map(PmsAccountRole::getRoleId).collect(Collectors.toSet());

        // 查询所有角色列表
        LambdaQueryWrapper<PmsRole> wrapper = new LambdaQueryWrapper<PmsRole>()
                .eq(PmsRole::getAliveFlag, AliveFlagEnum.ALIVE.getKey());
        wrapper.orderByDesc(PmsRole::getId);
        List<PmsRole> roleList = pmsRoleMapper.selectList(wrapper);
        return roleList.stream().map(item -> {
            ListRoleWithGrantStatusResp resData = new ListRoleWithGrantStatusResp();
            resData.setId(item.getId());
            resData.setRoleName(item.getRoleName());
            resData.setWorkbenchId(item.getWorkbenchId());
            resData.setWorkbenchCode(item.getWorkbenchCode());
            resData.setCreateDate(item.getCreateDate());
            resData.setUpdateDate(item.getUpdateDate());
            resData.setGrantedFlag(grantedRoleIds.contains(item.getId()));
            return resData;
        }).collect(Collectors.toList());
    }

    @Override
    public void addRole(AddRoleReq req) {
        UserInfo userInfo = UserUtil.getUserInfoWithExistCheck();
        List<PmsRole> roles = pmsRoleMapper.selectList(new LambdaQueryWrapper<PmsRole>()
                .eq(PmsRole::getRoleName, req.getRoleName())
                .eq(PmsRole::getWorkbenchCode, req.getWorkbenchCode())
                .eq(PmsRole::getAliveFlag, AliveFlagEnum.ALIVE.getKey()));
        if(CollUtil.isNotEmpty(roles)){
            throw new PmsException(PmsException.Type.PMS_0007);
        }

        PmsWorkbench workbench = pmsWorkbenchMapper.selectOne(new LambdaQueryWrapper<PmsWorkbench>()
                .eq(PmsWorkbench::getWorkbenchCode, req.getWorkbenchCode())
                .eq(PmsWorkbench::getAliveFlag, AliveFlagEnum.ALIVE.getKey()));
        if(workbench == null){
            throw new PmsException(PmsException.Type.PMS_0005);
        }

        PmsRole role = new PmsRole();
        role.setRoleName(req.getRoleName());
        role.setWorkbenchId(workbench.getId());
        role.setWorkbenchCode(workbench.getWorkbenchCode());
        role.setCreateUser(userInfo.getAccountId());
        role.setCreateDate(new Date());
        pmsRoleMapper.insert(role);
    }

    @Override
    public void updateRole(UpdateRoleReq req) {
        UserInfo userInfo = UserUtil.getUserInfoWithExistCheck();
        PmsRole currentRole = pmsRoleMapper.selectById(req.getRoleId());

        Integer count = pmsRoleMapper.selectCount(new LambdaQueryWrapper<PmsRole>()
                .ne(PmsRole::getId, req.getRoleId())
                .eq(PmsRole::getRoleName, req.getRoleName())
                .eq(PmsRole::getWorkbenchCode, currentRole.getWorkbenchCode())
                .eq(PmsRole::getAliveFlag, AliveFlagEnum.ALIVE.getKey()));
        if(count > 0){
            throw new PmsException(PmsException.Type.PMS_0007);
        }

        PmsRole role = new PmsRole();
        role.setId(currentRole.getId());
        role.setRoleName(req.getRoleName());
        role.setUpdateUser(userInfo.getAccountId());
        role.setUpdateDate(new Date());
        pmsRoleMapper.updateById(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(DeleteRoleReq req) {
        UserInfo userInfo = UserUtil.getUserInfoWithExistCheck();
        // 1.删除角色
        PmsRole role = new PmsRole();
        role.setId(req.getRoleId());
        role.setAliveFlag(AliveFlagEnum.DELETED.getKey());
        role.setUpdateUser(userInfo.getAccountId());
        role.setUpdateDate(new Date());
        pmsRoleMapper.updateById(role);

        // 2.删除角色相关的权限信息、接口信息、账号信息
        PmsAccountRole accountRole = new PmsAccountRole();
        accountRole.setAliveFlag(AliveFlagEnum.DELETED.getKey());
        accountRole.setUpdateUser(userInfo.getAccountId());
        accountRole.setUpdateDate(new Date());
        pmsAccountRoleMapper.update(accountRole, new LambdaQueryWrapper<PmsAccountRole>()
                .eq(PmsAccountRole::getRoleId, req.getRoleId())
                .eq(PmsAccountRole::getAliveFlag, AliveFlagEnum.ALIVE.getKey()));

        PmsRoleApi pmsRoleApi = new PmsRoleApi();
        pmsRoleApi.setAliveFlag(AliveFlagEnum.DELETED.getKey());
        pmsRoleApi.setUpdateUser(userInfo.getAccountId());
        pmsRoleApi.setUpdateDate(new Date());
        pmsRoleApiMapper.update(pmsRoleApi, new LambdaQueryWrapper<PmsRoleApi>()
                .eq(PmsRoleApi::getRoleId, req.getRoleId())
                .eq(PmsRoleApi::getAliveFlag,AliveFlagEnum.ALIVE.getKey()));

        PmsRolePermission rolePermission = new PmsRolePermission();
        rolePermission.setAliveFlag(AliveFlagEnum.DELETED.getKey());
        rolePermission.setUpdateUser(userInfo.getAccountId());
        rolePermission.setUpdateDate(new Date());
        pmsRolePermissionMapper.update(rolePermission, new LambdaQueryWrapper<PmsRolePermission>()
                .eq(PmsRolePermission::getRoleId, req.getRoleId())
                .eq(PmsRolePermission::getAliveFlag,AliveFlagEnum.ALIVE.getKey()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void grantRole(GrantRoleReq req) {
        UserInfo userInfo = UserUtil.getUserInfoWithExistCheck();
        PmsAccount pmsAccount = pmsAccountMapper.selectOne(new LambdaQueryWrapper<PmsAccount>()
                .eq(PmsAccount::getMemAccountId, req.getMemAccountId())
                .eq(PmsAccount::getAliveFlag, AliveFlagEnum.ALIVE.getKey()));
        if(pmsAccount == null){
            throw new PmsException(PmsException.Type.PMS_0004);
        }

        // 1.删除原有的角色关系
        PmsAccountRole deleteParam = new PmsAccountRole();
        deleteParam.setAliveFlag(AliveFlagEnum.DELETED.getKey());
        deleteParam.setUpdateUser(userInfo.getAccountId());
        deleteParam.setUpdateDate(new Date());
        pmsAccountRoleMapper.update(deleteParam, new LambdaQueryWrapper<PmsAccountRole>()
                .eq(PmsAccountRole::getAccountId, pmsAccount.getId())
                .eq(PmsAccountRole::getAliveFlag, AliveFlagEnum.ALIVE.getKey()));

        // 2.新增新的角色关系
        for (Long roleId : req.getRoleIds()) {
            PmsAccountRole insertParam = new PmsAccountRole();
            insertParam.setAccountId(pmsAccount.getId());
            insertParam.setRoleId(roleId);
            insertParam.setCreateUser(userInfo.getAccountId());
            insertParam.setCreateDate(new Date());
            pmsAccountRoleMapper.insert(insertParam);
        }
    }
}
